(function (){

    function rnd(max){ return Math.round(Math.random()*max); }

    _TD = {
        "firstName":["Andrew","Victor","Robert","John","Michael","James",
                    "William","David","Richard","Charles","Thomas","Paul","Mark",
                    "Geroge","Steven","Anthony","Kevin","Jason","Matthew",
                    "Mary","Patricia","Victoria","Linda","Barbara","Elizabeth",
                    "Jennifer","Maria","Susan","Margaret","Dorothy","Lisa",
                    "Nancy","Karen","Betty","Helen","Sandra","Carol","Ruth"],
        "lastName":["Smith","Johnson","Williams","Brown","Jones","Miller","Davis",
                    "Garcia","Wilson","Anderson","Taylor","Thomas","Moore","Jackson",
                    "White","Lee","Gonzalez","Harris","Clark","Lewis","Robison"],
        "favoriteColor":["blue","orange","green","yellow","black","red","purple","white","gray"],
        "favoriteCar":["Ford","Toyota","BMW","VW","Mercedes","Honda","Subaru"],
        "favoriteNumber":["1","2","3","4","5","6","7","8","9","10","11","12"],
        "monthBorn":["Jan","Feb","Mar","Apr","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],
        "favoriteColors":function(){
            var c = rnd(2)+1;
            var colors = []; 
            for(var i=0;i<c;++i){colors.push(genText("favoriteColor"));} 
            return colors.join(",");
        }, 
        "favoriteMonths":function(){
            var c = rnd(2)+1;
            var colors = []; 
            for(var i=0;i<c;++i){colors.push(genText("monthBorn"));} 
            return colors.join(",");
        } 
    };

    genRandomText = (function(){
        function genTextImpl(l){
            var n = ("number" == typeof l)?l:rnd(20);
            var chars = [];
            for(var i=0;i<n;++i){chars.push(rnd(255));}
            return String.fromCharCode.apply(null,chars); 
        }
        return genTextImpl;
    })();

    genText = (function(){
        function genTextImpl(l){
            var d = _TD[""+l];
            if (_TD.hasOwnProperty(""+l)){
                if ("function" == typeof d){return d();}
                return d[rnd(d.length-1)]; 
            }else{
                return genRandomText(l);
            }
        }
        return genTextImpl;
    })();

    escapeText = (function(){
        function escTextImpl(t){
            return (/(\"|,|\n|\r)/.test(t))?"\""+t.replace(/\"/g,"\"\"")+"\"":t;
        }
        return escTextImpl;
    })();

    unescapeText = (function(){
        function unescTextImpl(t){
            return (/^\"/.test(t))?t.slice(1,-1).replace(/\"\"/g,"\""):t;
        }
        return unescTextImpl;
    })();

    function genRecord(h){var r=[]; for (var i=0;i<h.length;++i){r.push(escapeText(genText(h[i])));} return r.join(',');}
    function genCSV(c,h){var r=[]; for (var i=0;i<c;++i){r.push(genRecord(h));} return r.join('\n');}

    jsCSVTester = function (){ 
        if ( !(this instanceof jsCSVTester) ) { return new jsCSVTester(); }
    }

    jsCSVTester.prototype.genRandomText = genRandomText;
    jsCSVTester.prototype.escapeText = escapeText;
    jsCSVTester.prototype.unescapeText = unescapeText;
    jsCSVTester.prototype.genCSV = genCSV;

    jsCSVTester.genRandomText = genRandomText;
    jsCSVTester.escapeText = escapeText;
    jsCSVTester.unescapeText = unescapeText;
    jsCSVTester.genCSV = genCSV;

    if('object' == typeof exports){
	module.exports = jsCSVTester;
    }

})();

